﻿#region
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

#endregion

namespace GFTradePlat
{
	/// <summary>
	/// </summary>
	public class ChartDB : Chart
	{
		/// <summary>
		/// </summary>
		public ChartDB()
		{
			SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
			UpdateStyles();
			AxisViewChanged += (obj, e) => { this.ResetAxisY(); };
			PreviewKeyDown += (obj, e) =>
			                  {
				                  switch (e.KeyData)
				                  {
					                  case Keys.Up:
						                  this.ZoomOut();
						                  break;
					                  case Keys.Down:
						                  this.ZoomIn();
						                  break;
					                  case Keys.Left:
						                  if (e.Control)
						                  {
							                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.LargeDecrement);
						                  }
						                  else
						                  {
							                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.SmallDecrement);
						                  }
						                  this.ResetAxisY();
						                  break;
					                  case Keys.Right:
						                  if (e.Control)
						                  {
							                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.LargeIncrement);
						                  }
						                  else
						                  {
							                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.SmallIncrement);
						                  }
						                  this.ResetAxisY();
						                  break;
					                  case Keys.Home:
						                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.First);
						                  this.ResetAxisY();
						                  break;
					                  case Keys.End:
						                  ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.Last);
						                  this.ResetAxisY();
						                  break;
				                  }
			                  };
		}

		/// <summary>
		/// 	Y值最小变动
		/// </summary>
		public double YValueTick { get; set; }

		/// <summary>
		/// </summary>
		/// <param name="e"> </param>
		public void Init()
		{
			//this.BackColor = Color.Transparent;
			Series[0].Name = "0";
			ChartAreas[0].BackColor = Color.WhiteSmoke;
			ChartAreas[0].AxisX.IsStartedFromZero = false;
			ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
			ChartAreas[0].AxisX.MajorGrid.LineColor = Color.LightCyan;
			ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dot;
			ChartAreas[0].AxisX.MajorTickMark.Enabled = false;
			ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
			ChartAreas[0].AxisY.IsStartedFromZero = false;
			ChartAreas[0].AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
			ChartAreas[0].AxisY.MajorGrid.LineColor = Color.DarkRed;
			ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
			ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
			ChartAreas[0].AxisY.ScaleView.Zoomable = false; //Y轴不缩放
			ChartAreas[0].AxisY.ScrollBar.Enabled = false; //Y轴不显示滚动条
			ChartAreas[0].AxisY.IsInterlaced = true; //交错显示
			ChartAreas[0].BorderColor = Color.Maroon;
			ChartAreas[0].BorderWidth = 1;
			ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
			Legends.Clear();
			Series[0].IsXValueIndexed = true;
			Series[0].XValueType = ChartValueType.Date;
			Series[0].ChartType = SeriesChartType.Candlestick;
			Series[0].CustomProperties = "PriceDownColor=Teal, PriceUpColor=Maroon";
			//this.Series[0].Color = Color.Red;
			//this.Series[0].MarkerStyle = MarkerStyle.Circle;
			//this.Series[0].MarkerColor = Color.White;
			//this.Series[0].MarkerBorderColor = Color.Red;
			Series[0].ToolTip = "时:#VALX\n开:#VALY3\n高:#VALY1\n低:#VALY2\n收:#VALY4";
			//this.Series[0].LabelToolTip = "#VALX\n#VALY3{N1}\n#VALY1{N1}\n#VALY2{N1}\n#VALY4{N1}";
		}

		internal void ResetAxisY()
		{
			if (ChartAreas[0].AxisX.ScaleView.IsZoomed)
			{
				Series sCur = Series[0];
				int left = Math.Max(0, (int) ChartAreas[0].AxisX.ScaleView.ViewMinimum);
				int right = Math.Min(sCur.Points.Count - 1, (int) ChartAreas[0].AxisX.ScaleView.ViewMaximum);
				double viewTop = double.MinValue,
				       viewButtom = double.MaxValue;
				////调整纵坐标
				//for (int i = left; i <= right; i++)
				//{
				//    viewTop = Math.Max(viewTop, this.Series[0].Points[i].YValues[0]);
				//    viewButtom = Math.Min(viewButtom, this.Series[0].Points[i].YValues[this.Series[0].YValuesPerPoint > 1 ? 1 : 0]);
				//}
				////viewTop += 10 * YValueTick;
				////viewButtom -= 10 * YValueTick;
				//viewTop *= 1.01;
				//viewButtom *= 0.99;
				//this.ChartAreas[0].AxisY.ScaleView.Zoom(viewButtom, viewTop);
				for (int i = 0; i < ChartAreas.Count; i++)
				{
					viewTop = double.MinValue;
					viewButtom = double.MaxValue;
					if (ChartAreas[i].Visible)
					{
						foreach (var s in Series.Where(n => n.ChartArea == ChartAreas[i].Name))
						{
							for (int j = left; j <= right; j++)
							{
								viewTop = Math.Max(viewTop, s.Points[j].YValues[0]);
								viewButtom = Math.Min(viewButtom, s.Points[j].YValues[s.YValuesPerPoint > 1 ? 1 : 0]);
							}
						}
						//viewTop += 10 * YValueTick;
						//viewButtom -= 10 * YValueTick;
						//viewTop = (Math.Ceiling(viewTop / 100) + 1) * 100;// *= 1.01;
						//viewButtom = viewButtom / 100 * 100;// *= 0.99;
						//viewTop = viewTop / this.YValueTick * this.YValueTick;
						//viewButtom = viewButtom / this.YValueTick * this.YValueTick;
						double baseY = Math.Pow(10, Math.Max(0, Math.Ceiling(viewTop).ToString().Length - 3));
						if (baseY == 1)
						{
							viewTop = Math.Ceiling(viewTop);
							viewButtom = Math.Floor(viewButtom);
						}
						else
						{
							viewTop = Math.Ceiling(viewTop/baseY)*baseY + baseY;
							viewButtom = Math.Floor(viewButtom/baseY)*baseY - baseY;
						}
						ChartAreas[i].AxisY.ScaleView.Zoom(viewButtom, viewTop);
					}
				}
			}
		}

		/// <summary>
		/// 	缩放
		/// </summary>
		public void Zoom()
		{
			if (Series[0].Points.Count > 200)
			{
				ChartAreas[0].AxisX.ScaleView.Zoom(Series[0].Points.Count - 150, Series[0].Points.Count);
				this.ResetAxisY();
			}
			else
			{
				ChartAreas[0].AxisX.ScaleView.ZoomReset();
				ChartAreas[0].AxisY.ScaleView.ZoomReset();
			}
		}

		/// <summary>
		/// 	放大
		/// </summary>
		public void ZoomOut()
		{
			if (!ChartAreas[0].AxisX.ScaleView.IsZoomed)
			{
				this.Zoom();
			}
			Series sCur = Series[0];
			int left = (int) ChartAreas[0].AxisX.ScaleView.ViewMinimum;
			int right = (int) ChartAreas[0].AxisX.ScaleView.ViewMaximum;
			if (right - left > 20)
			{
				ChartAreas[0].AxisX.ScaleView.Zoom(left + (right - left)/3, right);
				this.ResetAxisY();
			}
		}

		/// <summary>
		/// 	缩小
		/// </summary>
		public void ZoomIn()
		{
			if (ChartAreas[0].AxisX.ScaleView.IsZoomed)
			{
				Series sCur = Series[0];
				int left = (int) ChartAreas[0].AxisX.ScaleView.ViewMinimum;
				int right = (int) ChartAreas[0].AxisX.ScaleView.ViewMaximum;
				if (left <= 1 && right >= sCur.Points.Count)
				{
					ChartAreas[0].AxisX.ScaleView.ZoomReset();
					ChartAreas[0].AxisY.ScaleView.ZoomReset();
				}
				else
				{
					if (left == 0)
					{
						ChartAreas[0].AxisX.ScaleView.Zoom(left, right + (right - left)/3);
					}
					else
					{
						ChartAreas[0].AxisX.ScaleView.Zoom(left - (right - left)/3, right);
					}
					this.ResetAxisY();
				}
			}
		}
	}
}
